import {UIElement, UIPanel} from "../../js/threejs/libs/ui.js";

export default class DeviceToolLabelDialog {
  #signals
  #displayer
  #resetPositionHandle
  #id

  constructor(displayer) {
    this.#signals = displayer.signals
    this.#displayer = displayer
  }

  createLabelDialog = (labelConfig, position) => {
    let scope = this
    let labelDialogClass = `dialog label-dialog ${labelConfig.instanceId} ${labelConfig.id}`
    this.#id = labelDialogClass
    /* 加载style */
    if (labelConfig.style) {
      this.loadCssCode(labelConfig.id, labelConfig.style)
    }
    if (document.getElementsByClassName(labelDialogClass).length > 0) return false;
    let labelDialog = new UIPanel()
    labelDialog.setClass(labelDialogClass)
    this.labelDialog = labelDialog

    labelDialog.dom.addEventListener('mousedown', ev => {
      ev.stopImmediatePropagation()
      ev.stopPropagation()
    })
    labelDialog.dom.addEventListener('click', ev => {
      ev.stopImmediatePropagation()
      ev.stopPropagation()
    })
    labelDialog.dom.addEventListener('dblclick', ev => {
      ev.stopImmediatePropagation()
      ev.stopPropagation()
    })

    /* 设置位置 */
    let p = this.#displayer.transPosition(position)
    let menuP = this.labelPosition(labelDialog, p)
    labelDialog.setStyle('left', [menuP.x + 'px'])
    labelDialog.setStyle('top', [menuP.y + 'px'])

    let viewport = document.getElementById('viewport')
    viewport.appendChild(labelDialog.dom)
    let header = new UIPanel()
    header.setClass('header')
    /* 标题 */
    const title = this.isShowTitle(labelConfig)
    if (title) {
      header.add(title)
    }
    /* 延时关闭 */
    const delayClose = this.isDelayClose(labelDialog, labelConfig);
    /* 关闭按钮 */
    const closeButton = this.isShowCloseButton(labelConfig);
    if (closeButton) {
      closeButton.dom.addEventListener('mousedown', (e) => {
        e.stopPropagation()
        e.stopImmediatePropagation()
        this.#signals.removeLabel.dispatch(labelDialog)
        displayer.labelObjects.forEach((value, index, array) => {
          if (value.labelDialog === labelDialog) {
            value = null
            array.splice(index, 1)
          }
        })
      })
      header.add(closeButton)
      // 如果是延时关闭时，修改关闭按钮的颜色
      if (delayClose) {
        closeButton.dom.firstChild.setAttribute('stroke', 'red')
      }
      // 有关闭按钮 无标题时
      if (!title) {
        labelDialog.setStyle('padding-right', ['24px'])
      }
    }

    /* 标题隐藏 && 无关闭按钮 时，删除标题栏 */
    if (title || closeButton) {
      labelDialog.add(header)
    }

    let ul = new UIElement(document.createElement('ul'))
    labelDialog.add(ul)
    labelConfig["viewData"].map((vd) => {
      let li = new UIElement(document.createElement('li'))
      li.setClass(`item ${vd.key}`)
      li.dom.innerHTML = `<span class="name">${vd.name}：</span><span class="value">${vd.value}</span>`
      if (vd.metadata) {
        li.dom.innerHTML += `<span class="unit">${vd.metadata['unitSymbol']}</span>`
      }
      ul.add(li)
    })

    this.#signals.cameraChanged.add(scope.resetPosition, this);
    this.#signals.removeLabel.add(scope.removeLabel, this)
  }

  removeLabel = (labelDialog) => {
    let scope = this
    if (!labelDialog) {
      labelDialog = this.labelDialog
    }
    if (labelDialog === this.labelDialog) {
      this.#signals.cameraChanged.remove(this.resetPosition, this)

      labelDialog.dom.remove()
      labelDialog.remove()
      this.#signals.removeLabel.remove(this.removeLabel, this)
      scope = null
    }
  }

  /* 标签重新定位 */
  timer = null
  resetPosition = () => {
    let scope = this

    this.labelDialog.setStyle('display', ['none'])
    clearTimeout(this.timer)
    this.timer = setTimeout(() => {
      let object = scope.#displayer.objectByUuid(this.labelDialog.dom.classList[2])
      if (object) {
        scope.labelDialog.setStyle('display', ['block'])
        let p = scope.#displayer.transPosition(object.position)
        let labelP = scope.labelPosition(scope.labelDialog, p)
        scope.labelDialog.setStyle('left', [labelP.x + 'px'])
        scope.labelDialog.setStyle('top', [labelP.y + 'px'])
        /* 判断label之间和enum是否有重叠 */
        scope.checkLabelIntersect(scope.labelDialog)
      }
    }, 400)
  }

  checkLabelIntersect = (labelDialog) => {
    const labels = document.getElementsByClassName('label-dialog') || []
    for (let label of labels) {
      if (label.classList[2] !== labelDialog.dom.classList[2]) {
        let isIntersect = displayer.checkIntersect(label, labelDialog.dom);
        // console.log(isIntersect, labelDialog.dom.classList[2], label.classList[2])
        if (isIntersect) {
          labelDialog.setStyle('display', ['none'])
        } else {
          labelDialog.setStyle('display', ['block'])
        }
      }
    }
  }

  /**
   * 计算menu的平面坐标
   * @param labelDialog
   * @param point 点击位置
   */
  labelPosition = (labelDialog, point) => {
    let labelPosition = {x: point.x, y: point.y}
    // labelDialog的尺寸
    let width = labelDialog.dom.offsetWidth || 0
    let height = labelDialog.dom.offsetHeight || 0

    if (point.x + width > this.#displayer.VIEWPORT_WIDTH) {
      // 右侧超出
      labelPosition.x = this.#displayer.VIEWPORT_WIDTH - width
    }
    if (point.y + height > this.#displayer.VIEWPORT_HEIGHT) {
      // 下侧超出
      labelPosition.y = this.#displayer.VIEWPORT_HEIGHT - height
    }
    if (point.x < 0) {
      // 左侧超出
      labelPosition.x = 0
    }
    if (point.y < 0) {
      // 上侧超出
      labelPosition.y = 0
    }
    return labelPosition;
  }

  /**
   * 是否延时关闭
   * @param labelDialog
   * @param labelConfig
   */
  isDelayClose(labelDialog, labelConfig) {
    if (labelConfig['closeMethod'].indexOf('delay') > -1) {
      setTimeout(() => {
        labelDialog.dom.remove()
      }, (labelConfig['displayDuration'] || 1) * 1000)
      return true
    }
    return false
  }

  /**
   * 是否显示关闭按钮
   * @param labelConfig
   * @returns {null|UIElement}
   */
  isShowCloseButton(labelConfig) {
    if (labelConfig['closeMethod'].indexOf('no_close') === -1) {
      // 关闭按钮
      const closeSvg = (function () {
        let svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
        svg.setAttribute('width', 28)
        svg.setAttribute('height', 24)
        let path = document.createElementNS('http://www.w3.org/2000/svg', 'path')
        path.id = 'label-close-btn_' + labelConfig.instanceId + '_' + labelConfig.id
        path.setAttribute('d', 'M 12,12 L 22,22 M 22,12 12,22')
        path.setAttribute('stroke', 'aqua')
        svg.appendChild(path)
        return svg
      })()
      let close = new UIElement(closeSvg)
      close.setPosition('absolute')
      close.setTop('0')
      close.setRight('0')
      close.setCursor('pointer')
      return close
    }
    return null
  }

  /**
   * 显示标题
   * @param labelConfig
   */
  isShowTitle(labelConfig) {
    if (!labelConfig['hideTitle']) {
      let title = new UIElement(document.createElement('span'))
      title.setTextContent(labelConfig.title)
      return title
    }
    return null
  }

  loadCssCode(id, css) {
    let style = document.getElementById(id);
    if (style) {
      style.remove()
      // return
    }
    console.log('loadCssCode:', id, css)
    style = document.createElement('style');
    style.id = id
    style.type = 'text/css';
    style.rel = 'stylesheet';
    try {
      //for Chrome Firefox Opera Safari
      style.appendChild(document.createTextNode(css));
    } catch (ex) {
      //for IE
      style.styleSheet.cssText = css;
    }
    var head = document.getElementsByTagName('head')[0];
    head.appendChild(style);
  }
}